/**************************************************************************************************
* Title: SumOrderedArray.h
* Author: Gael Huber
* Description: Maintains a standard array that is self-ordering
**************************************************************************************************/
#ifndef __SUMORDEREDARRAY_H__
#define __SUMORDEREDARRAY_H__

#include <assert.h>
#include <vector>
template <typename Type>
class OrderedArray {
public:
	// Iterator class for the ordered array
	class Iterator;

public:
	// Defalt constructor (default capacity is 4)
	OrderedArray(void);

	// Copy constructor
	OrderedArray(const OrderedArray<Type>& rhs);

	// Destructor
	~OrderedArray(void);

	// Assignment operator
	OrderedArray<Type>& operator=(const OrderedArray<Type>& rhs);

	// Equivalence operator
	bool operator==(const OrderedArray<Type>& rhs) const;

	// Non-equivalence operator
	bool operator!=(const OrderedArray<Type>& rhs) const; 
	
	// Insert
	void insert(const Type& val);

	// Splice (index, length)
	void splice(int index, int length);

	// Splice (val)
	void splice(const Type& val);

	// Splice all (val)
	void splice_all(const Type& val);

	// Find
	int find(const Type& val) const;
	
	// Accessor for the array
	Type& operator[](int index) const;

	// Count
	int getCount(void) const;

	// Capacity
	int getCapacity(void) const;

	// Return an iterator at the start of the array
	Iterator begin(void) const;

	// Return an iterator at the end of the array
	Iterator end(void) const;

private:
	// Grow the array
	void grow(void);

	Type* data;
	int count;
	int capacity;
};

/**************************************************************************************************
* Iterator for the ordered array
**************************************************************************************************/
template <typename Type>
class OrderedArray<Type>::Iterator {
public:
	// Default constructor
	Iterator(void);

	// Constructor given pointer to element in array
	Iterator(Type* data);

	// Copy constructor
	Iterator(const Iterator& rhs);

	// Destructor
	~Iterator(void);

	// Return the data referenced
	Type& operator*(void) const;

	// Return a pointer to the class object
	Type* operator->(void) const;

	// Pre-increment
	Iterator& operator++(void);
	
	// Post-increment
	Iterator operator++(int rhs);

	// Pre-decrement
	Iterator& operator--(void);

	// Post-decrement
	Iterator operator--(int rhs);

	// Increment by integer
	Iterator& operator+=(int rhs);

	// Return this + integer
	Iterator operator+(int rhs) const;

	// Decrement by integer
	Iterator& operator-=(int rhs);

	// Return this - integer
	Iterator operator-(int rhs) const;

	// Return difference of iterators
	int operator-(const Iterator& rhs) const;

	// Return the data held
	Type& operator[](int rhs) const;

	// Equivanlence operator
	bool operator==(const Iterator& rhs) const;

	// Non-equivalence
	bool operator!=(const Iterator& rhs) const;

	// Less than operator
	bool operator<(const Iterator& rhs) const;

	// Greater than operator
	bool operator>(const Iterator& rhs) const;

	// Less than or equals operator
	bool operator<=(const Iterator& rhs) const;

	// Greater than or equals operator
	bool operator>=(const Iterator& rhs) const;

private:
	// Pointer to the data element in the ordered array
	Type* data;
};

#include "SumOrderedArray.inl"
#include "SumOrderedArrayIterator.inl"

#endif